package persistence.user;

import java.sql.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import model.User;

public class UseDAOJDBC implements UserDAO {

    private final Object lockOfTheConexion = new Object();
    private Connection conexion = null;
    private static UseDAOJDBC persistenceManager = null;
    private static final Logger logger = Logger.getLogger(UseDAOJDBC.class.getName());

    UseDAOJDBC() {
    }

    public static UseDAOJDBC getJDBCPersistenceManager() {
        if (persistenceManager == null) {
            persistenceManager = new UseDAOJDBC();
        }
        return persistenceManager;
    }

    @Override
    public boolean setUp(String url, String driver, String user, String password) {
        try {
            Class.forName(driver);
            conexion = DriverManager.getConnection(url, user, password);
        } catch (ClassNotFoundException ex) {
            logger.log(Level.SEVERE, "No se encontro el driver para la base de datos", ex);
            return false;
        } catch (SQLException ex) {
            logger.log(Level.SEVERE, "No se pudo establecer la conexion con la base de datos", ex);
            return false;
        }
        return true;
    }

    @Override
    public boolean disconnect() {
        try {
            conexion.close();
        } catch (SQLException ex) {
            logger.log(Level.SEVERE, "Conexi�n a la base de datos no cerrada", ex);
            return false;
        }
        return true;
    }

    @Override
    public boolean createUser(User user) {
        String query = "insert into\"USUARIOS\" values(?,?,?,?,?,?,?)";
        PreparedStatement statement;
        try {
            synchronized (lockOfTheConexion) {
                statement = conexion.prepareStatement(query);
            }
            statement.setString(1, user.getUsuario().toUpperCase());
            statement.setString(2, user.getPassword().toUpperCase());
            statement.setString(3, user.getCorreo());
            statement.setString(4, user.getNombre());
            statement.setString(5, user.getApellido());
            statement.setString(6, user.getDireccion());
            statement.setString(7, user.getPago());
            statement.execute();
            return true;
        } catch (SQLException ex) {
            logger.log(Level.SEVERE, "Error al crear un usuario", ex);
            return false;
        }
    }

    @Override
    public boolean deleteUser(String name) {
        String query = "delete from \"USUARIOS\" where USUARIO = ?";
        PreparedStatement statement;
        try {
            synchronized (lockOfTheConexion) {
                statement = conexion.prepareStatement(query);
            }
            statement.setString(1, name.toUpperCase());
            statement.execute();
            return true;
        } catch (SQLException ex) {
            logger.log(Level.SEVERE, "Error al borrar usuario", ex);
            return false;
        }
    }

    @Override
    public boolean updateUser(User user) {
        String query = null;
        query = "update \"USUARIOS\" SET USUARIO = ?,PASSWORD = ?,CORREO = ?,NOMBRE = ?,"
                + " APELLIDO = ?, DIRECCION = ?, PAGO = ? where USUARIO = ?";
        PreparedStatement statement;
        try {
            synchronized (lockOfTheConexion) {
                statement = conexion.prepareStatement(query);
            }
            statement.setString(1, user.getUsuario().toUpperCase());
            statement.setString(2, user.getPassword().toUpperCase());
            statement.setString(3, user.getCorreo());
            statement.setString(4, user.getNombre());
            statement.setString(5, user.getApellido());
            statement.setString(6, user.getDireccion());
            statement.setString(7, user.getPago());
            statement.setString(8, user.getUsuario().toUpperCase());

            statement.execute();
            return true;
        } catch (SQLException ex) {
            logger.log(Level.SEVERE, "Error al actualizar el usuario", ex);
            return false;
        }
    }

    @Override
    public User confirmUser(String name, String password) {
        String query = null;
        query = "select * from \"USUARIOS\" where USUARIO = ? and PASSWORD = ?";
        PreparedStatement statement;
        ResultSet resultSet = null;
        User user = null;
        try {
            synchronized (lockOfTheConexion) {
                statement = conexion.prepareStatement(query);
            }
            statement.setString(1, name.toUpperCase());
            statement.setString(2, password.toUpperCase());
            resultSet = statement.executeQuery();
            if (resultSet.next()) {
                user = new User();
                user.setUsuario(resultSet.getString("USUARIO").toLowerCase());
                user.setPassword(resultSet.getString("PASSWORD").toLowerCase());
                user.setCorreo(resultSet.getString("CORREO"));
                user.setNombre(resultSet.getString("NOMBRE"));
                user.setApellido(resultSet.getString("APELLIDO"));
                user.setDireccion(resultSet.getString("DIRECCION"));
                user.setPago(resultSet.getString("PAGO"));

            }
        } catch (SQLException ex) {
            logger.log(Level.SEVERE, "Error al recuperar usuario", ex);
            user = null;

        } finally {
            if (resultSet != null) {
                try {
                    resultSet.close();
                } catch (SQLException ex) {
                    logger.log(Level.SEVERE, "Error al cerrar la conexon a la base de datos", ex);
                }
            }
        }
        return user;
    }

    @Override
    public User readUser(String name) {
        String query = null;
        query = "select * from \"USUARIOS\" where USUARIO = ?";
        PreparedStatement statement;
        ResultSet resultSet = null;
        User user = null;
        try {
            synchronized (lockOfTheConexion) {
                statement = conexion.prepareStatement(query);
            }
            statement.setString(1, name.toUpperCase());
            resultSet = statement.executeQuery();
            if (resultSet.next()) {
                user = new User();
                user.setUsuario(resultSet.getString("USUARIO").toLowerCase());
                user.setPassword(resultSet.getString("PASSWORD").toLowerCase());
                user.setCorreo(resultSet.getString("CORREO"));
                user.setNombre(resultSet.getString("NOMBRE"));
                user.setApellido(resultSet.getString("APELLIDO"));
                user.setDireccion(resultSet.getString("DIRECCION"));
                user.setPago(resultSet.getString("PAGO"));

            }
        } catch (SQLException ex) {
            logger.log(Level.SEVERE, "Error al recuperar usuario", ex);
            user = null;

        } finally {
            if (resultSet != null) {
                try {
                    resultSet.close();
                } catch (SQLException ex) {
                    logger.log(Level.SEVERE, "Error al cerrar la conexon a la base de datos", ex);
                }
            }
        }
        return user;
    }

    public void setConnection(Connection conexion) {
        synchronized (lockOfTheConexion) {
            this.conexion = conexion;
        }
    }
}
